#include "stm32f10x.h"                  // Device header
#include "I2C.h"
#include "MPU6050_Reg.h"

#define MPU6050_ADDRESS 0xD0
/**
   *@brief     封装I2C_CheckEvent实现超时跳出
   *@parem  	 哪个I2C,哪个事件
   *@retval    无
   */
void I2C_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{
	//超时退出
	uint16_t Num = 10000;
	while(I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS)
	{
		Num--;
		if(Num == 0) break;
	}
}

void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data)
{

	I2C_GenerateSTART(I2C2,ENABLE);																					//产生起始位,并切换的主机模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT);                       //等待起始位产生完毕
	                                                                        //
	I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Transmitter);    //发送从机地址,写模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);         //等待发送从机地址完毕
	                                                                        //
	I2C_SendData(I2C2,RegAddress);                                          //发送寄存器地址
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);                 //等待数据移位寄存器开始移位
	                                                                        //
	I2C_SendData(I2C2,Data);                                                //发送数据
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);                  //等待数据移位寄存器和数据寄存器为空
	                                                                        //
	I2C_GenerateSTOP(I2C2,ENABLE);                                          //停止
}


/*
uint8_t MPU6050_limitedReadReg()
{
	uint8_t Byte = 0x00;
	
	MyI2C_Start();
	MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
	MyI2C_ReceiveAck();
	Byte = MyI2C_ReceiveByte();
	MyI2C_SendAck(1);
	MyI2C_Stop();
	return Byte;
}
*/
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
	/*
	MyI2C_Start();
	MyI2C_SendByte(MPU6050_ADDRESS);
	MyI2C_ReceiveAck();
	MyI2C_SendByte(RegAddress);
	MyI2C_ReceiveAck();
	return MPU6050_limitedReadReg();*/
	uint8_t Byte = 0x00;
	
	I2C_GenerateSTART(I2C2,ENABLE);																					//产生起始位,并切换的主机模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT);                       //等待起始位产生完毕
	                                                                        //
	I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Transmitter);    //发送从机地址,写模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);         //等待发送从机地址完毕
	                                                                        //
	I2C_SendData(I2C2,RegAddress);                                          //发送寄存器地址
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);                  //等待数据移位寄存器和数据寄存器为空
	
	I2C_GenerateSTART(I2C2,ENABLE);																					//产生起始位,并切换的主机模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT);                       //等待起始位产生完毕
	                                                                        //
	I2C_Send7bitAddress(I2C2,MPU6050_ADDRESS,I2C_Direction_Receiver);    		//发送从机地址,读模式
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);         		//等待发送从机地址完毕
	
	I2C_AcknowledgeConfig(I2C2,DISABLE);                                    //给非应答
	I2C_GenerateSTOP(I2C2,ENABLE);                                          //停止
	
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);         						//等待数据寄存器非空
	Byte = I2C_ReceiveData(I2C2);                                           //读取数据寄存器数据
	
	I2C_AcknowledgeConfig(I2C2,ENABLE);                                    //给应答
	
	return Byte;
}

void MPU6050_Init()
{
	//MyI2C_Init();
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);							//开启I2C2的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);						//开启GPIOB的时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;									//复用开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               //
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;        //10,11引脚
 	GPIO_Init(GPIOB, &GPIO_InitStructure);                          
	
	I2C_InitTypeDef I2C_InitStruct;
	I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;																	//给应答
	I2C_InitStruct.I2C_ClockSpeed = 50000;                                    //通讯速度为50KHz
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;                           //低高占空比为2:1
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;                                   //I2C模式
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;    //地址7字节
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;                                    //从模式时的地址为0x00
	I2C_Init(I2C2,&I2C_InitStruct);
	
	I2C_Cmd(I2C2,ENABLE);
	                                                                          
	MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0x01);                                //关闭休眠,使用x轴陀螺仪时钟
	MPU6050_WriteReg(MPU6050_PWR_MGMT_2,0x00);                                //循环频率为0,不循环,每个轴都不待机
	MPU6050_WriteReg(MPU6050_SMPLRT_DIV,0x09);																//10分频 0
	MPU6050_WriteReg(MPU6050_CONFIG,0x06);                                    //无外部同步,低通滤波器为6
	MPU6050_WriteReg(MPU6050_GYRO_CONFIG,0x18);                               //不自测,满量程
	MPU6050_WriteReg(MPU6050_ACCEL_CONFIG,0x18);                              //不自测,满量程,不用高通滤波器
}
/**
   *@brief     根据小端模式(即高地址存高数据)把所有数据存入MPU6050DatasStruct结构体中
   *@parem  	 MPU6050DatasStruct结构体的地址
   *@retval    无
   */
/*
void MPU6050_GetData(MPU6050DatasTypeDef* MPU6050DatasStruct)
{
	uint8_t* PData = (uint8_t*)MPU6050DatasStruct;
	uint8_t i = 0;
	for(i = 0;i<14;i+=2)
  {
		*(PData + i + 1) = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H + i);
		*(PData + i) = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H + i + 1);
  }
}*/

/*
void MPU6050_GetData(MPU6050DatasTypeDef* MPU6050DatasStruct)
{
	uint8_t* PData = (uint8_t*)MPU6050DatasStruct;
	uint8_t i = 0;
	for(i = 0;i<14;i++)
  {
		
		*PData = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L - i);
		PData++;
  }
}
*/
/*
void MPU6050_GetData(MPU6050DatasTypeDef* MPU6050DatasStruct)
{
	uint8_t* PData = (uint8_t*)MPU6050DatasStruct;
	uint8_t i = 0;
	
	MyI2C_Start();
	MyI2C_SendByte(MPU6050_ADDRESS);
	MyI2C_ReceiveAck();
	MyI2C_SendByte(MPU6050_ACCEL_XOUT_H);
	MyI2C_ReceiveAck();

	MyI2C_Start();
	MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
	MyI2C_ReceiveAck();
	for(i = 0;i < 14;i+=2)
  {
		*(PData + i + 1) = MyI2C_ReceiveByte();
		MyI2C_SendAck(0);
		*(PData + i) = MyI2C_ReceiveByte();
		if(i != 12)	MyI2C_SendAck(0);	
  }
	MyI2C_SendAck(1);
	MyI2C_Stop();
}
*/